import { ref, reactive, onActivated, nextTick } from 'vue';
import type { Ref } from 'vue';

export interface ListConfig {
  psize: number;
  pindex: number;
}

export type Result<T> = T[];
export type OnPage<T = any> = (listConfig: ListConfig) => Promise<Result<T>>;

/**
 * 列表加载
 * onPage 加载函数
 * isActive 是否为缓存页面开启优化 默认false
 * @returns {list,loading,finished,refreshing,onLoad,onRefresh}
 */
export function useList<T = any>(onPage: OnPage<T>, isActive = false) {
  const list: Ref<Result<T>> = ref([]);
  const loading = ref(false);
  const finished = ref(false);
  const error = ref(false);
  const refreshing = ref(false);
  const listConfig = reactive({
    psize: 10,
    pindex: 1,
  });

  const onLoad = async (cur = false) => {
    loading.value = true;
    try {
      // 开启Current状态下，只请求已加载数据，不分页（只在有数据的情况下开启）
      const Current = cur && list.value.length > 0;
      const result = await onPage(
        Current ? { psize: listConfig.psize * Math.ceil(list.value.length / listConfig.psize), pindex: 1 } : listConfig
      );
      // 重置下拉刷新
      if (refreshing.value) {
        refreshing.value = false;
      }
      // 列表赋值
      if (listConfig.pindex === 1 || Current) {
        list.value = result;
      } else {
        list.value.push(...result);
      }
      // 检查暂无更多
      if (result.length < listConfig.psize) {
        finished.value = true;
      } else {
        !Current && listConfig.pindex++;
      }
    } catch (err) {
      error.value = true;
      console.error('err: ', err);
    } finally {
      loading.value = false;
    }
  };

  const onRefresh = (clear = false) => {
    // 清空列表数据
    error.value = false;
    finished.value = false;
    listConfig.pindex = 1;
    if (clear === true) {
      list.value = [];
    }
    // 重新加载数据
    onLoad();
  };

  // 刷新列表当前位置（针对缓存页面）
  const onRefreshCurrent = () => {
    onLoad(true);
  };

  // 缓存页面优化
  if (isActive) {
    onActivated(() => {
      nextTick(() => {
        if (!loading.value) {
          onRefreshCurrent();
        }
      });
    });
  }

  return {
    listConfig,
    list,
    loading,
    finished,
    error,
    refreshing,
    onLoad,
    onRefresh,
    onRefreshCurrent,
  };
}
